home *** CD-ROM | disk | FTP | other *** search
- /*
- * Project: <none>
- *
- * Filename: FinderObjects.c
- *
- * Author: Marco Piovanelli
- *
- * Revision History:
- *
- * 1996.06.02 MP created this file
- *
- */
-
-
- #include "FinderObjects.h"
- #include "Utilities.h"
-
- #ifndef __ALIASES__
- #include <Aliases.h>
- #endif
-
- #ifndef __APPLEEVENTS__
- #include <AppleEvents.h>
- #endif
-
- #ifndef __AEREGISTRY__
- #include <AERegistry.h>
- #endif
-
- #ifndef __GESTALT__
- #include <Gestalt.h>
- #endif
-
- enum
- {
- kFinderType = 'FNDR',
- kFinderSignature = 'MACS'
- } ;
-
- OSErr FindProcess ( OSType inProcessType, OSType inProcessSignature, ProcessSerialNumber * outPSN ) ;
- OSErr CreateFinderEvent ( AEEventClass inEventClass, AEEventID inEventID, AppleEvent * outAE ) ;
-
- OSErr FindProcess ( OSType inProcessType, OSType inProcessSignature, ProcessSerialNumber * outPSN )
- {
- ProcessInfoRec info ;
-
- // start at beginning of process list
- outPSN -> lowLongOfPSN = kNoProcess ;
- outPSN -> highLongOfPSN = kNoProcess ;
-
- // init process info record
- BlockClear ( & info, sizeof ( info ) ) ;
- info . processInfoLength = sizeof ( info ) ;
-
- // walk the process list, looking for the given creator
- while ( ( GetNextProcess ( outPSN ) == noErr ) &&
- ( GetProcessInformation ( outPSN, & info ) == noErr ) )
- {
- if ( ( info . processType == inProcessType ) && ( info . processSignature == inProcessSignature ) )
- {
- return noErr ;
- }
- }
-
- return procNotFound ;
- }
-
- inline OSErr FinderPSN ( ProcessSerialNumber * outPSN )
- {
- return FindProcess ( kFinderType, kFinderSignature, outPSN ) ;
- }
-
- OSErr CreateFinderEvent ( AEEventClass inEventClass, AEEventID inEventID, AppleEvent * outAE )
- {
- ProcessSerialNumber finderPSN ;
- AEAddressDesc finderAddress ;
- OSErr err ;
-
- InitDesc ( outAE ) ;
- InitDesc ( & finderAddress ) ;
-
- // find the process serial number of the Finder
- if ( ( err = FinderPSN ( & finderPSN ) ) != noErr )
- goto cleanup ;
-
- // create an address descriptor for the target application based on the PSN
- if ( ( err = AECreateDesc ( typeProcessSerialNumber, & finderPSN, sizeof ( finderPSN ), & finderAddress ) ) != noErr )
- goto cleanup ;
-
- // create the Apple event
- if ( ( err = AECreateAppleEvent ( inEventClass, inEventID, & finderAddress, kAutoGenerateReturnID, kAnyTransactionID, outAE ) ) != noErr )
- goto cleanup ;
-
- // clear result code
- err = noErr;
-
- cleanup:
- ForgetDesc ( & finderAddress ) ;
- return err ;
- }
-
- static Boolean HasScriptableFinder ( void )
- {
- SInt32 response ;
-
- return ( ( Gestalt ( gestaltFinderAttr, & response ) == noErr ) &&
- ( response & ( 1L << gestaltOSLCompliantFinder ) ) ) ;
- }
-
- OSErr OpenFinderObject ( const FSSpec * inThing )
- {
- FSSpec thing = * inThing ;
- AppleEvent ae, reply ;
- AEDesc thingAlias, parentAlias, thingList ;
- ProcessSerialNumber finderPSN ;
- OSErr err ;
-
- InitDesc ( & ae ) ;
- InitDesc ( & reply ) ;
- InitDesc ( & thingAlias ) ;
- InitDesc ( & parentAlias ) ;
- InitDesc ( & thingList ) ;
-
- // create a minimal alias for the specified object
- if ( ( err = NewAliasMinimal ( & thing, ( AliasHandle * ) & thingAlias . dataHandle ) ) != noErr )
- goto cleanup ;
- thingAlias . descriptorType = typeAlias ;
-
- if ( HasScriptableFinder ( ) )
- {
- // if the Finder is OSL-compliant, we can send it a
- // straightforward "open" (aevt/odoc) event
- if ( ( err = CreateFinderEvent ( kCoreEventClass, kAEOpen, & ae ) ) != noErr )
- goto cleanup ;
-
- // the direct parameter of the event is simply the file alias
- if ( ( err = AEPutParamDesc ( & ae, keyDirectObject, & thingAlias ) ) != noErr )
- goto cleanup ;
- }
- else
- {
- // older, non-OSL-compliant, Finders (from version 7.0 onward)
- // require a custom "open selection" event (FNDR/sope) with much
- // more complicated parameters
-
- if ( ( err = CreateFinderEvent ( kAEFinderEvents, kAEOpenSelection, & ae ) ) != noErr )
- goto cleanup ;
-
- // create a full alias for the parent directory (enclosing folder)
- // of specified object; if the object is at root level, create a full
- // alias for the object itself
- if ( thing . parID != fsRtParID )
- {
- if ( ( err = FindParentSpec ( & thing ) ) != noErr )
- goto cleanup ;
- }
- if ( ( err = NewAlias ( nil, & thing, ( AliasHandle * ) & parentAlias . dataHandle ) ) != noErr )
- goto cleanup ;
- parentAlias . descriptorType = typeAlias;
-
- // add the alias record for the parent directory to the Apple event, as direct object
- if ( ( err = AEPutParamDesc ( & ae, keyDirectObject, & parentAlias ) ) != noErr )
- goto cleanup ;
-
- // create a list of descriptors for the objects to show
- if ( ( err = AECreateList ( nil, 0, false, & thingList ) ) != noErr )
- goto cleanup ;
- if ( ( err = AEPutDesc ( & thingList, 0, & thingAlias ) ) != noErr )
- goto cleanup ;
-
- // add the object list to the Apple event, as a keySelection parameter
- if ( ( err = AEPutParamDesc ( & ae, keySelection, & thingList ) ) != noErr )
- goto cleanup ;
- }
-
- // bring the Finder to the foreground
- if ( ( err = FinderPSN ( & finderPSN ) ) != noErr )
- goto cleanup ;
- if ( ( err = SetFrontProcess ( & finderPSN ) ) != noErr )
- goto cleanup ;
-
- // send the apply event
- if ( ( err = AESend ( & ae, & reply, kAENoReply + kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil ) ) != noErr )
- goto cleanup ;
-
- // clear result code
- err = noErr ;
-
- cleanup:
- ForgetDesc ( & ae ) ;
- ForgetDesc ( & reply ) ;
- ForgetDesc ( & thingAlias ) ;
- ForgetDesc ( & parentAlias ) ;
- ForgetDesc ( & thingList ) ;
-
- return err ;
- }
-